import 'package:easy_chat_app/commons/GlobalStatus.dart';
import 'package:easy_chat_app/commons/db/repository/LocalConversationRepository.dart';
import 'package:easy_chat_app/commons/db/repository/LocalMessageRepository.dart';
import 'package:easy_chat_app/commons/db/service/LocalConversationService.dart';
import 'package:easy_chat_app/commons/db/service/LocalMessageService.dart';
import 'package:easy_chat_app/commons/model/AppSendMessageReq.dart';
import 'package:easy_chat_app/commons/model/GetChatGroupDetailResultData.dart';
import 'package:easy_chat_app/commons/model/GetContactsUserInfoResultData.dart';
import 'package:easy_chat_app/commons/model/GetUserChatGroupInfoListItem.dart';
import 'package:easy_chat_app/commons/model/InboxMessage.dart';
import 'package:easy_chat_app/commons/model/Result.dart';
import 'package:easy_chat_app/commons/utils/HttpUtils.dart';
import 'package:easy_chat_app/commons/utils/RouteUtils.dart';
import 'package:easy_chat_app/commons/utils/StringUtils.dart';
import 'package:easy_chat_app/commons/widget/UserHeadPortrait.dart';
import 'package:easy_chat_app/mobile/constants/MobileAppGlobalConstants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';

class MobileChatPageParams {
  int? currentUserId;
  String? currentUserNickName;
  String? currentUserCode;
  String? currentUserHeadPortrait;
  String? currentUserHeadPortraitStoreType;

  int? contactUserId;
  String? contactUserNickname;
  String? contactUserCode;
  String? contactUserHeadPortrait;
  String? contactUserHeadPortraitStoreType;

  LocalConversation? localConversation;

  GetUserChatGroupInfoListResultData? chatGroupDetail;

  MobileChatPageParams(
      {this.contactUserId,
      this.contactUserCode,
      this.contactUserNickname,
      this.contactUserHeadPortrait,
      this.contactUserHeadPortraitStoreType,
      this.currentUserId,
      this.currentUserCode,
      this.currentUserNickName,
      this.currentUserHeadPortrait,
      this.currentUserHeadPortraitStoreType,
      this.localConversation,
      this.chatGroupDetail});
}

class MobileChatPageDataChangeNotifier extends ChangeNotifier {
  List<LocalMessage> localMessageList = [];

  LocalConversation? localConversation;

  String globalStatusVersion = "";

  Future<void> reloadData(int conversationId) async {
    List<LocalMessage> msgList =
        await LocalMessageService.queryNewLocalMsg(100, conversationId);
    localMessageList = msgList;
    notifyListeners();
  }

  Future<void> loadMore(int conversationId) async {
    int msgCount = localMessageList.length + 100;
    localMessageList =
        await LocalMessageService.queryNewLocalMsg(msgCount, conversationId);

    localConversation =
        await LocalConversationService.getLocalConversationById(conversationId);
    notifyListeners();
  }

  @override
  String toString() {
    return 'MobileChatPageDataChangeNotifier{localMessageList: $localMessageList}';
  }
}

class MobileChatPage extends StatelessWidget {
  MobileChatPage({super.key});

  final Logger logger = Logger();

  @override
  Widget build(BuildContext context) {
    ScrollController msgListScrollController = ScrollController();
    MobileChatPageParams pageParams =
        RouteUtils.currentRouteSettings().arguments as MobileChatPageParams;
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) {
          var mobileChatPageDataChangeNotifier =
              MobileChatPageDataChangeNotifier();
          msgListScrollController.addListener(() {
            double pixels = msgListScrollController.position.pixels;
            double maxScrollExtent =
                msgListScrollController.position.maxScrollExtent;
            int localConversationId = pageParams.localConversation!.id!;
            if (pixels >= maxScrollExtent) {
              mobileChatPageDataChangeNotifier.loadMore(localConversationId);
            }
            if (pixels == 0) {
              mobileChatPageDataChangeNotifier.reloadData(localConversationId);
            }
          });
          return mobileChatPageDataChangeNotifier;
        })
      ],
      builder: (context, child) {
        Color backgroundColor = const Color.fromRGBO(237, 237, 237, 1);
        var msgInputTextEditingController = TextEditingController();
        String? titleText;
        LocalConversation localConversation = pageParams.localConversation!;
        Map<int, GetUserChatGroupInfoListResultDataChatGroupUserItem>
            chatGroupUserItemMap = {};
        if (localConversation.type == LocalConversationTypeConstants.general) {
          titleText = pageParams.contactUserNickname ?? "";
        } else {
          GetUserChatGroupInfoListResultData chatGroupDetail =
              pageParams.chatGroupDetail!;
          titleText = chatGroupDetail.name ??
              "群聊(${chatGroupDetail.chatGroupUserItemList?.length})";
          for (GetUserChatGroupInfoListResultDataChatGroupUserItem item
              in (chatGroupDetail.chatGroupUserItemList ?? [])) {
            chatGroupUserItemMap[item.id!] = item;
          }
        }
        return Scaffold(
          appBar: AppBar(
            title: Text(
              titleText,
              style: const TextStyle(color: Colors.black),
            ),
            actions: [
              IconButton(
                  onPressed: () async {
                    logger.i("action more");
                    LocalConversation localConversation =
                        pageParams.localConversation!;
                    if (localConversation.type ==
                        LocalConversationTypeConstants.group) {
                      int chatGroupId = pageParams.chatGroupDetail!.id!;
                      GetChatGroupDetailResultData? chatGroupDetail =
                          (await HttpUtils.getChatGroupDetail(chatGroupId))
                              .data!;
                      await RouteUtils.route2MobileChatGroupInfoPage(
                          chatGroupDetail: chatGroupDetail);
                    }
                    if (localConversation.type ==
                        LocalConversationTypeConstants.general) {
                      int contactsUserId = pageParams.contactUserId!;
                      GetContactsUserInfoResultData contactsUserInfo =
                          (await HttpUtils.getContactsUserInfo(contactsUserId))
                              .data!;
                      await RouteUtils.route2MobileContactsInfoPage(
                          contactsUserInfo, localConversation, MobileChatPage);
                    }
                  },
                  icon: const Icon(Icons.more_horiz))
            ],
            centerTitle: true,
            surfaceTintColor: MobileAppGlobalConstants.appBarSurfaceTintColor,
            backgroundColor: MobileAppGlobalConstants.appBarBackgroundColor,
          ),
          body: Container(
            height: double.infinity,
            width: double.infinity,
            color: backgroundColor,
            child: Column(
              children: [
                Container(
                  width: double.infinity,
                  height: 1,
                  color: const Color.fromRGBO(215, 215, 215, 1),
                ),
                Expanded(child:
                    Consumer2<MobileChatPageDataChangeNotifier, GlobalStatus>(
                        builder: (context, mobileChatPageDataChangeNotifier,
                            globalStatus, child) {
                  int conversationId = pageParams.localConversation!.id!;
                  if (mobileChatPageDataChangeNotifier.globalStatusVersion ==
                      "") {
                    mobileChatPageDataChangeNotifier.globalStatusVersion =
                        globalStatus.getVersion();
                    mobileChatPageDataChangeNotifier.reloadData(conversationId);
                  } else {
                    LocalConversationService.getLocalConversationById(
                            conversationId)
                        .then((newLocalConversation) async {
                      /// 如果会话没有更新，不需要刷新列表
                      if (newLocalConversation?.updateTime !=
                          mobileChatPageDataChangeNotifier
                              .localConversation?.updateTime) {
                        double? pixels =
                            msgListScrollController.position.pixels;
                        if (pixels == 0) {
                          mobileChatPageDataChangeNotifier.globalStatusVersion =
                              globalStatus.getVersion();
                          await mobileChatPageDataChangeNotifier
                              .loadMore(conversationId);
                        }
                      }
                    });
                  }
                  return messageList(
                      mobileChatPageDataChangeNotifier,
                      pageParams,
                      msgListScrollController,
                      chatGroupUserItemMap);
                })),
                Container(
                  width: double.infinity,
                  height: 1,
                  color: const Color.fromRGBO(215, 215, 215, 1),
                ),
                CupertinoApp(
                  debugShowCheckedModeBanner: false,
                  home: Container(
                    color: const Color.fromRGBO(246, 246, 246, 1),
                    child: Container(
                      alignment: Alignment.center,
                      margin: const EdgeInsets.only(
                          left: 10, right: 10, top: 10, bottom: 30),
                      child: Row(
                        children: [
                          Expanded(
                              child: Container(
                            color: Colors.white,
                            child: Consumer<MobileChatPageDataChangeNotifier>(
                                builder: (context, value, child) {
                              return CupertinoTextField(
                                maxLines: 3,
                                minLines: 1,
                                maxLength: 1000,
                                controller: msgInputTextEditingController,
                                decoration: const BoxDecoration(border: null),
                                textInputAction: TextInputAction.send,
                                onEditingComplete: () async {
                                  await sendMsg(
                                      msgInputTextEditingController,
                                      msgListScrollController,
                                      pageParams,
                                      value);
                                },
                              );
                            }),
                          ))
                        ],
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
        );
      },
    );
  }

  Widget messageList(
      MobileChatPageDataChangeNotifier data,
      MobileChatPageParams pageParams,
      ScrollController msgListScrollController,
      Map<int, GetUserChatGroupInfoListResultDataChatGroupUserItem>
          chatGroupUserItemMap) {
    int currentUserId = pageParams.currentUserId!;
    return Container(
      width: double.infinity,
      height: double.infinity,
      alignment: Alignment.topCenter,
      child: ListView.builder(
          shrinkWrap: true,
          addAutomaticKeepAlives: false,
          addRepaintBoundaries: false,
          reverse: true,
          controller: msgListScrollController,
          itemCount: data.localMessageList.length,
          itemBuilder: (context, index) {
            LocalMessage msg = data.localMessageList[index];
            if (msg.sourceUserId == currentUserId) {
              return Container(
                margin: const EdgeInsets.only(
                    left: 65, right: 10, top: 10, bottom: 10),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Flexible(
                        flex: 1,
                        fit: FlexFit.loose,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10),
                          child: Container(
                            color: const Color.fromRGBO(148, 238, 110, 1),
                            padding: const EdgeInsets.all(10),
                            child: Text(
                              StringUtils.defaultIfEmpty(msg.message, ""),
                              style: const TextStyle(fontSize: 18),
                            ),
                          ),
                        )),
                    const SizedBox(
                      width: 8,
                    ),
                    UserHeadPortrait.network(
                        size: 40,
                        userCode: pageParams.currentUserCode!,
                        userHeadPortrait: pageParams.currentUserHeadPortrait!,
                        userHeadPortraitStoreType:
                            pageParams.currentUserHeadPortraitStoreType!)
                  ],
                ),
              );
            } else {
              LocalConversation localConversation =
                  pageParams.localConversation!;
              Widget userHeadPortrait;
              if (localConversation.type ==
                  LocalConversationTypeConstants.general) {
                userHeadPortrait = UserHeadPortrait.network(
                    size: 40,
                    userCode: pageParams.contactUserCode!,
                    userHeadPortrait: pageParams.contactUserHeadPortrait!,
                    userHeadPortraitStoreType:
                        pageParams.contactUserHeadPortraitStoreType!);
              } else {
                GetUserChatGroupInfoListResultDataChatGroupUserItem
                    chatGroupUserItem = chatGroupUserItemMap[msg.sourceUserId]!;
                userHeadPortrait = UserHeadPortrait.network(
                    size: 40,
                    userCode: chatGroupUserItem.code!,
                    userHeadPortrait: chatGroupUserItem.headPortrait!,
                    userHeadPortraitStoreType:
                        chatGroupUserItem.headPortraitStoreType!);
              }
              return Container(
                margin: const EdgeInsets.only(
                    left: 10, right: 65, top: 10, bottom: 10),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    userHeadPortrait,
                    const SizedBox(
                      width: 8,
                    ),
                    Flexible(
                        flex: 1,
                        fit: FlexFit.loose,
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(10),
                          child: Container(
                            color: const Color.fromRGBO(148, 238, 110, 1),
                            padding: const EdgeInsets.all(10),
                            child: Text(
                              StringUtils.defaultIfEmpty(msg.message, ""),
                              style: const TextStyle(fontSize: 18),
                            ),
                          ),
                        ))
                  ],
                ),
              );
            }
          }),
    );
  }

  Future<void> sendMsg(
      TextEditingController msgInputTextEditingController,
      ScrollController msgListScrollController,
      MobileChatPageParams pageParams,
      MobileChatPageDataChangeNotifier value) async {
    var content = msgInputTextEditingController.text;
    logger.i("content: $content");
    if (content.isEmpty) {
      return;
    }
    LocalConversation localConversation = pageParams.localConversation!;
    LocalMessage message = LocalMessage.create(
        conversationId: localConversation.id,
        sourceUserId: pageParams.currentUserId,
        targetUserId: pageParams.contactUserId,
        chatGroupId: pageParams.chatGroupDetail?.id,
        chatType: localConversation.type,
        messageType: 0,
        message: content,
        sendTime: DateTime.now().millisecondsSinceEpoch,
        status: LocalMessageStatusConstants.readyToSend,
        messageSource: LocalMessageMessageSourceConstants.inbox,
        readState: LocalMessageReadState.read);
    logger.i("message:$message");
    await LocalMessageService.addLocalMessage(message);
    await LocalConversationService.setNewestMsg(
        pageParams.localConversation!.id!,
        DateTime.now().millisecondsSinceEpoch,
        message.message!,
        message.messageType!);
    msgInputTextEditingController.text = "";
    value.reloadData(pageParams.localConversation!.id!);
    Result<InboxMessage?> result = await HttpUtils.sendMessage(
        AppSendMessageReq.create(
            conversationType: localConversation.type,
            targetUserId: message.targetUserId,
            chatGroupId: message.chatGroupId,
            messageType: message.messageType,
            message: message.message));
    if (result.data != null) {
      LocalMessageService.completeMessageSending(
          message.localMsgId, result.data?.sendTime?.millisecondsSinceEpoch);
    }

    Future.delayed(const Duration(milliseconds: 150)).then((v) {
      msgListScrollController
          .jumpTo(msgListScrollController.position.minScrollExtent);
    });
  }
}
